use std::{env::temp_dir, sync::Arc};

use dfs::inode::{inode_root, DirCreateOptions};
use manage::SiminkManage;
use monitor::{MonitorBuilder, MonitorPrompt};
use rcu::soft_rcu_init;
use tracelog::tracelog_init;

use crate::{
    board::board_init,
    cli::parse_cli,
    command::simink_monitor_registers,
    config::config_init,
    monitor::{monitor_init, SiminkMonitorPrompt},
};

/// 主程序初始化
///
/// # Panics
/// 系统中任意初始化不符合预期都有可能 panic
pub fn main_init() -> Arc<SiminkManage> {
    // 解析命令行参数
    let arg = parse_cli();
    // 启动 rcu
    let handle = soft_rcu_init();

    // 创建监视器
    let mon = Arc::new(
        MonitorBuilder::builder()
            .use_color(true)
            .quick_completions(true)
            .vi(true)
            .prompt(MonitorPrompt::new(Arc::new(SiminkMonitorPrompt)))
            .history(temp_dir().join("simink.history"))
            .build(),
    );

    let sysinode =
        DirCreateOptions::new().read_write(true).name("sys").create_dir(inode_root()).unwrap();
    // 创建 simink 管理数据结构
    let manage = Arc::new(SiminkManage::new(sysinode.clone(), handle.thread().id()));
    manage.push_worker(handle);

    simink_monitor_registers(mon.clone(), manage.clone());

    tracelog_init(sysinode, manage.clone());
    board_init(manage.clone());
    monitor_init(mon.clone(), manage.clone(), &arg);
    // 到这里基本初始化全部完成, 可以调用外部命令进一步配置系统
    config_init(mon, &arg);

    manage
}
